home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 41 / Amiga Format CD41 (1999-06)(Future Publishing)(GB)[!][issue 1999-07].iso / -seriously_amiga- / comms / www / streammp3 / streammp3.rx < prev   
Text File  |  1999-04-19  |  9KB  |  292 lines

  1. /* StreamMP3.rx by Sigbjørn (CISC) Skjæret
  2. ** $VER: StreamMP3.rx v2.21 (27.03.99)
  3. **
  4. ** Tries to stream a MP3 file via a file containing URL(s) (like a .m3u or .pls file)...
  5. */
  6. options results
  7. options failat 21
  8. signal on halt
  9. signal on break_c
  10. parse arg args
  11.  
  12.  
  13. /*** Edit these options ***/
  14.  
  15. mp3prog        = 'C:MPEGA'                            /* Which decoder to run */
  16. mp3args        = '-m -t2000 -F22050 -I0002000C'    /* Commandline arguments to the mp3 prog */
  17.  
  18. rxprog        = 'SYS:RexxC/RX'                    /* The ARexx interpreter */
  19.  
  20. bfsize        = '16384'                            /* Initial playback buffer (will revert to "pbsize" variable after first read) */
  21. pbsize        = '1024'                            /* Playback buffer (keep this low unless you have a very fast connection to the stream) */
  22.  
  23. save        = '0'                                /* Save file while streaming? (1 for yes, 0 for no) */
  24. savepath    = 'RAM:'                            /* Where to save the file while streaming */
  25. comment        = '1'                                /* Save URL as comment to the file saved? (1 for yes, 0 for no) */
  26.  
  27. reqtools    = '1'                                /* Display ReqTools requester? (1 for yes, 0 for no) */
  28. pubscreen    = 'Workbench'                        /* The public screen you want the requester on */
  29.  
  30. /*** <-end-> ***/
  31.  
  32.  
  33. if ~show('L','rxsocket.library') then
  34. do
  35.  if ~addlib('rxsocket.library',0,-30,0) then
  36.  do
  37.   say 'ARexx socket library not available, exiting'
  38.   exit 10
  39.  end
  40. end
  41.  
  42. if(reqtools) then
  43.  if ~show('L','rexxreqtools.library') then
  44.   if ~addlib('rexxreqtools.library',0,-30,0) then reqtools=0
  45.  
  46. if(~exists(mp3prog) | ~exists(rxprog)) then
  47. do
  48.  if ~exists(rxprog) then notfound=rxprog
  49.  else notfound=mp3prog
  50.  
  51.  say 'Sorry, "'notfound'" does not exist, please edit path in script.'
  52.  exit 10
  53. end
  54.  
  55. if(upper(word(args,1))='URL') then
  56. do
  57.  url=word(args,2)
  58.  mp3tmp=word(args,3)
  59.  call Stream()
  60.  
  61.  call close(pipe)
  62.  call CloseSocket(sock)
  63.  if(save) then
  64.  do
  65.   call close(file)
  66.   if(comment) then
  67.    if(shoutcast & name~=host & name~='') then address command 'FileNote "'savepath''filename''app'" "'name'"'
  68.    else address command 'FileNote "'savepath''filename''app'" http://'url
  69.  end
  70.  
  71.  exit
  72. end
  73. else if(upper(word(args,1))='BREAK') then
  74. do
  75.  pidtmp='pid'time('S')
  76.  address command 'Status >T:'pidtmp
  77.  call open(pid,'T:'pidtmp,R)
  78.  do while ~eof(pid)
  79.   line=readln(pid)
  80.   if(pos(mp3prog,line)>0) then
  81.   do
  82.    id=strip(word(line,2),'T',':');cmd=subword(line,6)
  83.    address command 'Break >NIL: 'id
  84.    say 'Sent Ctrl-C to process 'id': 'cmd
  85.   end
  86.  end
  87.  call close(pid)
  88.  address command 'Delete >NIL: T:'pidtmp' QUIET'
  89.  say 'Done.'
  90.  exit
  91. end
  92.  
  93. args=strip(args,'B','"')
  94.  
  95. parse source . . . pname;pname=subword(pname,1,words(pname)-2);found=0
  96.  
  97. if(pos(' ',pname)>0) then
  98. do
  99.  say 'Sorry, due to restrictions in RX, you''ll have to place "'pname'" somewhere where the path does not resolve with a space in it.'
  100.  exit 10
  101. end
  102.  
  103. if(args='') then
  104. do
  105.  if(pubscreen~='') then reqtags='rt_pubscrname='pubscreen
  106.  else reqtags=''
  107.  
  108.  if(reqtools) then url=rtgetstring(,'Enter URL:','Enter URL',,reqtags)
  109.  else do;say 'Enter URL:';parse pull url;end
  110.  
  111.  if(url='') then
  112.  do
  113.   say 'No URL entered .. exiting!'
  114.   exit
  115.  end
  116.  
  117.  if(pos('://',url)=0) then url='http://'url
  118.  call Play()
  119. end
  120. else if ~open(file,args,R) then
  121. do
  122.  say 'Unable to open file containing URL!!!'
  123.  exit 10
  124. end
  125. else do x=1 while ~eof(file)
  126.  url=readln(file);url=strip(strip(url,'T',d2c(13)),'B')
  127.  if(url='') then iterate x
  128.  
  129.  if(upper(left(url,4))='FILE') then url=substr(url,pos('=',url)+1)
  130.  
  131.  if(~abbrev(url,'http://',7)) then iterate x
  132.  
  133.  call Play()
  134. end
  135.  
  136. if ~found then
  137. do
  138.  say 'No supported URLs found!!!'
  139.  exit 10
  140. end
  141.  
  142. exit
  143.  
  144.  
  145. /*** PROCEDURES ***/
  146.  
  147. Play:
  148.  if(upper(right(url,4))='.M3U' | upper(right(url,4))='.PLS') then
  149.  do
  150.   url=strip(url,'L','http://');port='80';crlf=d2c(13)''d2c(10);lookup=1
  151.   if(pos('/',url)>0) then do;host=substr(url,1,pos('/',url)-1);path=substr(url,pos('/',url));end
  152.   else do;host=url;path='/';end
  153.   if(pos(':',host)>0) then do;port=substr(host,pos(':',host)+1);host=substr(host,1,pos(':',host)-1);end
  154.  
  155.   if ~GetHost('HOST',host) then;if(datatype(compress(host,'.'),'N')) then do;host.HOSTADDRLIST.0=host;lookup=0;end;else do;say 'Unable to lookup host!!!';iterate x;end
  156.   sock=Socket('INET','STREAM','IP');if sock<0 then do;say 'Unable to create socket!!!';iterate x;end
  157.   conn.ADDRFAMILY='INET';conn.ADDRPORT=port;conn.ADDRADDR=host.HOSTADDRLIST.0
  158.   if Connect(sock,'CONN')<0 then do;if(lookup) then say 'Sorry, server is down, unable to stream data!';else say 'Host does not exist!!!';iterate x;end
  159.  
  160.   req='GET 'path' HTTP/1.0'crlf''crlf
  161.   call Send(sock,req)
  162.  
  163.   len=1
  164.   do y=1 while len>0
  165.    len=recvline(sock,'BUF',1024)
  166.    if(buf=crlf) then
  167.    do z=1 while len>0
  168.     len=recvline(sock,'BUF',1024)
  169.     url=strip(strip(strip(buf,'T',d2c(10)),'T',d2c(13)),'B')
  170.     if(upper(left(url,4))='FILE') then url=substr(url,pos('=',url)+1)
  171.     if(url='') then iterate z
  172.     if(~abbrev(url,'http://',7)) then iterate z
  173.     leave y
  174.    end
  175.   end
  176.   call CloseSocket(sock)
  177.  end
  178.  
  179.  if(url='') then return 0
  180.  
  181.  mp3tmp='mp3'time('S');setclip(mp3tmp);found=1
  182.  address command 'Run >NIL: 'rxprog' 'pname' URL 'url' 'mp3tmp
  183.  
  184.  do i=1 to 15
  185.   address command 'Wait 5'
  186.   clip=getclip(mp3tmp)
  187.   if(clip='PLAY' | clip='SAVE' | clip='NOSAVE') then leave i
  188.   if(clip~='') then
  189.   do
  190.    say 'Failed: 'clip
  191.    setclip(mp3tmp)
  192.    return 0
  193.   end
  194.   if(i=15) then
  195.   do
  196.    say 'Operation timed out...'
  197.    setclip(mp3tmp,'DIE') /* Just in case */
  198.    return 0
  199.   end
  200.  end
  201.  
  202.  address command ''mp3prog' >NIL: 'mp3args' -r -n -b0 PIPE:'mp3tmp
  203.  setclip(mp3tmp,'DIE')
  204. return 0
  205.  
  206. Stream:
  207.  filename='';size='';name='';genre='';bitr='';shoutcast=0;app='';num=0
  208.  url=strip(url,'L','http://');port='80'
  209.  if(pos('/',url)>0) then do;host=substr(url,1,pos('/',url)-1);path=substr(url,pos('/',url));end
  210.  else do;host=url;path='/';end
  211.  if(pos(':',host)>0) then do;port=substr(host,pos(':',host)+1);host=substr(host,1,pos(':',host)-1);end
  212.  
  213.  if(savepath~='') then
  214.  do
  215.   if(right(savepath,1)~=':' & right(savepath,1)~='/') then savepath=savepath'/'
  216.   if(path='/') then filename=mp3tmp'.mp3'
  217.   else filename=substr(path,lastpos('/',path)+1)
  218.  end
  219.  
  220.  crlf=d2c(13)''d2c(10);lookup=1
  221.  
  222.  if ~GetHost('HOST',host) then;if(datatype(compress(host,'.'),'N')) then do;host.HOSTADDRLIST.0=host;lookup=0;end;else do;setclip(mp3tmp,'Unable to lookup host!!!');return 10;end
  223.  sock=Socket('INET','STREAM','IP');if sock<0 then do;setclip(mp3tmp,'Unable to create socket!!!');return 10;end
  224.  conn.ADDRFAMILY='INET';conn.ADDRPORT=port;conn.ADDRADDR=host.HOSTADDRLIST.0
  225.  if Connect(sock,'CONN')<0 then do;if(lookup) then setclip(mp3tmp,'Sorry, server is down, unable to stream data!');else setclip(mp3tmp,'Host does not exist!!!');return 10;end
  226.  
  227.  req='GET 'path' HTTP/1.0'crlf''crlf
  228.  call Send(sock,req)
  229.  
  230.  call open(pipe,'PIPE:'mp3tmp,W)
  231.  if(save) then do;call open(file,savepath''filename,W);num=1;end
  232.  
  233.  len=1;start=0
  234.  do y=1 while len>0
  235.   if(start) then
  236.   do
  237.    len=recv(sock,'BUF',bfsize);bfsize=pbsize
  238.    if(len>0) then
  239.    do
  240.     call writech(pipe,buf)
  241.     if(save) then call writech(file,buf)
  242.    end
  243.    clip=getclip(mp3tmp)
  244.    if(clip='DIE') then do;setclip(mp3tmp);return 0;end
  245.    if(clip='SAVE' & save=0) then do;save=1;num=num+1;if(num>1) then app='.'num;call open(file,savepath''filename''app,W);call writech(file,buf);end
  246.    if(clip='NOSAVE' & save=1) then do;save=0;call close(file);if(comment) then if(shoutcast & name~=host & name~='') then address command 'FileNote "'savepath''filename''app'" "'name'"';else address command 'FileNote "'savepath''filename''app'" http://'url;end
  247.   end
  248.   else
  249.   do
  250.    len=recvline(sock,'BUF',1024)
  251.    if(y=1 & word(buf,1)='ICY') then shoutcast=1
  252.    if(y=1 & word(buf,2)~='200') then do;setclip(mp3tmp,strip(subword(buf,3),'T',crlf));return 10;end
  253.    if(word(buf,1)='Content-Length:') then size=strip(word(buf,2),'T',crlf)
  254.    if(left(buf,9)='icy-name:') then name=compress(strip(substr(buf,10),'T',crlf),"'""")
  255.    if(left(buf,10)='icy-genre:') then genre=compress(strip(substr(buf,11),'T',crlf),"'""")
  256.    if(left(buf,7)='icy-br:') then bitr=strip(substr(buf,8),'T',crlf)
  257.    if(buf=crlf) then do;start=1;setclip(mp3tmp,'PLAY');call OpenReq();end
  258.   end
  259.  end
  260. return 0
  261.  
  262. OpenReq:
  263.  if(reqtools) then
  264.  do
  265.   lf=d2c(10)
  266.   stbt="'Start _Save'"
  267.   spbt="'Stop _Save'"
  268.   flsv="'"savepath""filename"'"
  269.  
  270.   if(size='') then size='Unknown'
  271.   else size=size' bytes'
  272.   if(save=0) then do;svfl="'No'";svbt=stbt;prbt=spbt;end
  273.   else do;svfl=flsv;svbt=spbt;prbt=stbt;end
  274.   if(name='') then name=host
  275.   if(genre='') then genre='Unknown'
  276.   if(bitr='') then bitr='Unknown'
  277.   else bitr=bitr'kbps'
  278.   if(pubscreen='') then reqtags="'rtez_flags=ezreqf_noreturnkey'"
  279.   else reqtags="'rt_pubscrname="pubscreen" rtez_flags=ezreqf_noreturnkey'"
  280.  
  281.   if(shoutcast) then req="'Host:  "strip(left(name,30))"...'l'Genre: "strip(left(genre,20))"...'l'Save:  'f''l'Rate:  "bitr"',s'|_Break','StreamMP3...',"reqtags
  282.   else req="'Host: "host"'l'File: "path"'l'Save: 'f''l'Size: "size"',s'|_Break','StreamMP3...',"reqtags
  283.  
  284.   address command 'Run >NIL: 'rxprog' "m='''mp3tmp''';l=d2c(10);f='svfl';s='svbt';p='prbt';do forever;call rtezrequest('req');if(rtresult=0) then;do;setclip(m,''DIE'');exit;end;else;do;t=p;p=s;s=t;if(length(p)=11) then setclip(m,''SAVE'');else setclip(m,''NOSAVE'');end;f='flsv';end"'
  285.  end
  286. return 0
  287.  
  288. Halt:
  289. Break_C:
  290.  setclip(mp3tmp,'DIE')
  291. exit
  292.